<?php
/**
 * 文件上传behaivor
 * @author yangdongqi <yangdongqi@hayzone.com>
 * @package lib.behaviors.ar
 */
class CFileSaveBehavior extends CActiveRecordBehavior {
	
	/**
	 * 需要保存的属性
	 * @var array
	 */
	public $attributes = array();
	
	/**
	 * 旧的文件路径
	 * @var array
	 */
	protected $_oldFilesPath = array();
	
	/**
	 * 新的文件路径
	 * @var array
	 */
	protected $_filesPath = array();
	
	/**
	 * CUploadedFile 的实例
	 * @var array
	 */
	protected $_files = array();
	
	/**
	 * 文件物理根目录
	 * @var string
	 */
	public $basePath = '';
	
	/**
	 * 文件根URL目录
	 * @var string
	 */
	public $baseUrl = '';
	
	/**
	 * 相对于根目录的文件目录
	 * @var string
	 */
	protected $_relativePath;
	
	/**
	 * counter
	 * @var array
	 */
	protected static $_counter = array();
	
	/**
	 * 获取属性的URL
	 * @param string $attribute
	 * @return string
	 */
	public function getAccessUrl($attribute) {
		return $this->baseUrl . $this->owner->$attribute;
	}
	
	public function getAccessPath($attribute) {
		return $this->basePath . $this->owner->$attribute;
	}
	
	public function getAccessBaseUrl($attribute) {
		return dirname($this->baseUrl . $this->owner->$attribute);
	}
	
	public function getAccessBasePath($attribute) {
		return dirname($this->basePath . $this->owner->$attribute);
	}
	
	public function getExtension($attribute) {
		$pathInfo = pathinfo($attribute);
		return $pathInfo[PATHINFO_EXTENSION];
	}
	
	public function getFileName($attribute) {
		return basename($this->owner->$attribute);
	}
	
	/**
	 * 准备CUploadedFile对象
	 * @see CModelBehavior::beforeValidate()
	 * @return void
	 */
	public function beforeValidate($event) {
		$model = $this->owner;
		foreach($this->attributes as $attribute) {
			$index = $this->objectIndex;
			$file = CUploadedFile::getInstance($model, $index.$attribute);
			$this->_oldFilesPath[$attribute] = $model->$attribute;
			if($file) $this->_files[$attribute] = $model->$attribute = $file;
		}
	}
	
	/**
	 * 还原文件路径
	 * @see CModelBehavior::afterValidate()
	 * @return void
	 */
	public function afterValidate($event) {
		foreach($this->attributes as $attribute) {
			$this->owner->$attribute = $this->_oldFilesPath[$attribute];
		}
	}
	
	/**
	 * 保存文件路径
	 * @see CActiveRecordBehavior::beforeSave()
	 * @return void
	 */
	public function beforeSave($event) {
		foreach($this->_files as $attribute => $file) {
			$this->owner->$attribute = $this->relativePath.$this->randName.'.'.$file->extensionName;	
		}
	}
	
	/**
	 * 保存文件
	 * @see CActiveRecordBehavior::afterSave()
	 * @return void
	 */
	public function afterSave($event) {
		$model = $this->owner;
		if(!empty($this->_files)) {
			foreach($this->_files as $attribute => $file) {
				$filePath = $this->basePath.$this->owner->$attribute;
				$dirname = dirname($filePath);
				if(!is_dir($dirname)) {
					mkdir($dirname, 0777, true);
				}
				$file->saveAs($filePath);
			}
		}
	}
	
	/**
	 * 获取$_FILES中对象所对应的下标
	 * @return string
	 */
	protected function getObjectIndex() {
		$className = get_class($this->owner);
		if(!isset($_FILES[$className])) return '';
		$files = $_FILES[$className];
		$element = reset($files['name']);
		if(is_array($element)) {
			if(!isset(self::$_counter[$className])) {
				self::$_counter[$className] = array(
					'index' => -1,
					'max' => count($files['name']),
					'keys' => array_keys($files['name']),
				);
			}
			$index = ++ self::$_counter[$className]['index'];
			if($index == self::$_counter[$className]['max']) {
				$index = self::$_counter[$className]['index'] = 0;
			}
			$index = self::$_counter[$className]['keys'][$index];
			return "[$index]";
		} else {
			return '';
		}
	}
	
	/**
	 * 随机文件名
	 * @return string
	 */
	public function getRandName() {
		return mktime().rand(12345, 98765);
	}
	
	/**
	 * 获取相对于basePath的文件完整路径
	 * @param string $attribute
	 * @return string
	 */
	public function getFullPath($attribute) {
		return $this->relativePath.$this->randName.'.'.$this->_files[$attribute]->getExtensionName();
	}
	
	/**
	 * 获取相对路径
	 * @return string
	 */
	public function getRelativePath() {
		if(!$this->_relativePath) {
			$this->_relativePath = date('/Y/m/d/');
		}
		return $this->_relativePath;
	}
	
}

?>